using Microsoft.EntityFrameworkCore;
using star_questionnair.Models;
using star_questionnair.Services;
using star_questionnair.Utilities;
using System.Collections.Generic;

public class QuestionnaireService : IQuestionnaireService
{
    private readonly ApplicationDbContext _dbContext;
    private readonly IQuestionService _questionService;
    private readonly IHistoryService _historyService;
    private readonly IOptionService _optionService;

    public QuestionnaireService(
        ApplicationDbContext dbContext,
        IQuestionService questionService,
        IHistoryService historyService, IOptionService optionService)
    {
        _dbContext = dbContext;
        _questionService = questionService;
        _historyService = historyService;
        _optionService = optionService;
    }

    public async Task<Questionnaire> InsertQuestionnaireAsync(int authorId, string title, string description)
    {
        var maxId = await SelectMaxIdAsync();
        var questionnaire = new Questionnaire
        {
            Id = maxId + 1,
            AuthorId = authorId,
            Title = title,
            Description = description,
            CreatedTime = DateTime.Now,
            Status = false
        };

        await _dbContext.Questionnaires.AddAsync(questionnaire);
        await _dbContext.SaveChangesAsync();
        return questionnaire;
    }

    public async Task<int> SelectMaxIdAsync()
    {
        return await _dbContext.Questionnaires.MaxAsync(q => (int?)q.Id) ?? 0;
    }

    public async Task<Questionnaire> GetQuestionnaireByIdAsync(int questionnaireId)
    {
        return await _dbContext.Questionnaires.FindAsync(questionnaireId);
    }

    public async Task UpdateQuestionnaireAsync(Questionnaire questionnaire)
    {
        var existingQuestionnaire = await GetQuestionnaireByIdAsync(questionnaire.Id);
        if (existingQuestionnaire == null)
            throw new InvalidOperationException("Questionnaire not found");

        // 更新字段
        existingQuestionnaire.Title = questionnaire.Title ?? existingQuestionnaire.Title;
        existingQuestionnaire.Description = questionnaire.Description ?? existingQuestionnaire.Description;
        existingQuestionnaire.UpdatedTime = DateTime.Now;

        _dbContext.Questionnaires.Update(existingQuestionnaire);
        await _dbContext.SaveChangesAsync();
    }

    public async Task DeleteQuestionnaireAsync(int questionnaireId)
    {
        var questionnaire = await GetQuestionnaireByIdAsync(questionnaireId);
        if (questionnaire == null) return;

        // 删除相关问题和选项
        var questions = await _dbContext.Questions
            .Where(q => q.QuestionnaireId == questionnaireId)
            .ToListAsync();

        foreach (var question in questions)
        {
            var options = await _dbContext.Options
                .Where(o => o.QuestionId == question.Id)
                .ToListAsync();

            _dbContext.Options.RemoveRange(options);
            _dbContext.Questions.Remove(question);
        }

        _dbContext.Questionnaires.Remove(questionnaire);
        await _dbContext.SaveChangesAsync();
    }

    public async Task UpdateDeadlineAsync(int questionnaireId, DateTime newDeadline)
    {
        var questionnaire = await GetQuestionnaireByIdAsync(questionnaireId);
        if (questionnaire == null)
            throw new InvalidOperationException("Questionnaire not found");

        questionnaire.Deadline = newDeadline;
        questionnaire.UpdatedTime = DateTime.Now;

        _dbContext.Questionnaires.Update(questionnaire);
        await _dbContext.SaveChangesAsync();
    }

    public async Task UpdateQuestionnaireStatusAsync(int questionnaireId)
    {
        var questionnaire = await GetQuestionnaireByIdAsync(questionnaireId);
        if (questionnaire == null)
            throw new InvalidOperationException("Questionnaire not found");

        questionnaire.Status = !questionnaire.Status;
        questionnaire.UpdatedTime = DateTime.Now;

        _dbContext.Questionnaires.Update(questionnaire);
        await _dbContext.SaveChangesAsync();
    }

    public async Task<int> GetQuestionnaireResponseCountAsync(int questionnaireId)
    {
        return await _dbContext.Responses
            .CountAsync(r => r.QuestionnaireId == questionnaireId);
    }

    // public async Task<Questionnaire> SubmitWholeQuestionnaireAsync(Questionnaire questionnaire)
    // {
    //     var title = questionnaire.Title;
    //     var suffix = 1;
    //
    //     while (await _dbContext.Questionnaires
    //                .AnyAsync(q => q.AuthorId == questionnaire.AuthorId && q.Title == questionnaire.Title))
    //     {
    //         questionnaire.Title = $"{title} ({suffix++})";
    //     }
    //
    //     await _dbContext.SaveChangesAsync(); // Ensure any changes are persisted here
    //
    //     await InsertQuestionnaireAsync(questionnaire.AuthorId, questionnaire.Title, questionnaire.Description);
    //     var newQuestionnaire = await GetQuestionnaireAfterCreateAsync(questionnaire.AuthorId, questionnaire.Title);
    //
    //     foreach (var question in questionnaire.Questions)
    //     {
    //         question.QuestionnaireId = newQuestionnaire.Id;
    //         await _questionService.InsertQuestionAsync(question.QuestionnaireId, question.Type, question.Content);
    //     }
    //
    //     // Ensure changes are committed before calling this method
    //     await _dbContext.SaveChangesAsync();
    //
    //     return _historyService.GetWholeQuestionnaire(newQuestionnaire.Id);
    // }

    public async Task<int> GetCountQuestionByAuthorAndTitleAsync(int authorId, string title)
    {
        // 使用 LINQ 查询满足条件的问卷数量
        return await _dbContext.Questionnaires
            .Where(q => q.AuthorId == authorId && q.Title == title)
            .CountAsync(); // 获取符合条件的问卷数量
    }

    public async Task<Questionnaire> SubmitWholeQuestionnaireAsync(Questionnaire questionnaire)
    {
        var title = questionnaire.Title;
        var suffix = 1;

        // 防止同名
        while (await _dbContext.Questionnaires
                   .AnyAsync(q => q.AuthorId == questionnaire.AuthorId && q.Title == questionnaire.Title))
        {
            questionnaire.Title = $"{title} ({suffix++})";
        }

        // 插入问卷
        await InsertQuestionnaireAsync(questionnaire.AuthorId, questionnaire.Title, questionnaire.Description);

        // 获取刚刚创建的问卷
        var newQuestionnaire = await GetQuestionnaireAfterCreateAsync(questionnaire.AuthorId, questionnaire.Title);

        // 初始化问题顺序
        int questionOrdination = 1;

        foreach (var question in questionnaire.Questions)
        {
            // 设置问卷 ID 和问题顺序
            question.QuestionnaireId = newQuestionnaire.Id;
            question.Ordination = questionOrdination++;

            // 插入问题
            await _questionService.InsertQuestionAsync(question.QuestionnaireId, question.Type, question.Content);

            // 获取插入后的问题 ID（异步方式）
            var insertedQuestion = await _questionService.GetQuestionAfterCreateAsync(question);
            question.Id = insertedQuestion.Id;

            // 初始化选项顺序
            int optionOrdination = 1;

            foreach (var option in question.Options)
            {
                option.Id = 0;
                // 设置问题 ID 和选项顺序
                option.QuestionId = question.Id;
                option.Ordination = optionOrdination++;

                // 插入选项（异步方式）
                await _optionService.SaveAsync(option);
            }
        }

        // 返回完整的问卷
        return await _historyService.GetQuestionnaireByIdAsync(newQuestionnaire.Id);
    }


    public async Task<Questionnaire> UpdateWholeQuestionnaireAsync(Questionnaire questionnaire)
    {
        var existingQuestionnaire = await GetQuestionnaireByIdAsync(questionnaire.Id);
        if (existingQuestionnaire == null)
            throw new InvalidOperationException("Questionnaire not found");

        existingQuestionnaire.Title = questionnaire.Title;
        existingQuestionnaire.Description = questionnaire.Description;

        // 删除旧问题和选项
        var questions = await _dbContext.Questions
            .Where(q => q.QuestionnaireId == questionnaire.Id)
            .ToListAsync();

        foreach (var question in questions)
        {
            var options = await _dbContext.Options
                .Where(o => o.QuestionId == question.Id)
                .ToListAsync();

            _dbContext.Options.RemoveRange(options);
            _dbContext.Questions.Remove(question);
        }

        await _dbContext.SaveChangesAsync();

        // 插入新问题和选项
        foreach (var question in questionnaire.Questions)
        {
            question.QuestionnaireId = questionnaire.Id;
            await _questionService.InsertQuestionAsync(question.QuestionnaireId, question.Type, question.Content);
            var insertedQuestion = await _questionService.GetQuestionAfterCreateAsync(question);
            
            foreach (var option in question.Options)
            {
                option.QuestionId = insertedQuestion.Id;
                option.Id = 0;
                await _optionService.SaveAsync(option);
            }
        }

        return _historyService.GetWholeQuestionnaire(questionnaire.Id);
    }

    public async Task DeleteWholeQuestionnaireAsync(int questionnaireId)
    {
        await DeleteQuestionnaireAsync(questionnaireId);
    }

    public async Task<Questionnaire> GetQuestionnaireAfterCreateAsync(int authorId, string title)
    {
        return await _dbContext.Questionnaires
            .FirstOrDefaultAsync(q => q.AuthorId == authorId && q.Title == title);
    }
}